package com.csun.cmny.provider.controller.rpc;

import com.csun.cmny.provider.device.csun.gateway.entity.CsunGatewayData;
import com.csun.cmny.provider.device.csun.sleep.entity.CsunSleepData;
import com.csun.cmny.provider.model.domain.DmcDevice;
import com.csun.cmny.provider.model.dto.csunbutton.BedOldmanCsunButtonReqDto;
import com.csun.cmny.provider.model.dto.device.DeviceBindDto;
import com.csun.cmny.provider.model.dto.device.DeviceReqDto;
import com.csun.cmny.provider.model.enums.csunsleep.DmcCsunSleepBindTypeEnum;
import com.csun.cmny.provider.model.enums.device.DeviceStatusEnum;
import com.csun.cmny.provider.model.enums.device.DmcDeviceTypeEnum;
import com.csun.cmny.provider.model.vo.*;
import com.csun.cmny.provider.model.vo.csunsleep.CsunSleepVo;
import com.csun.cmny.provider.vo.DmcCsunSleepDataVo;
import com.csun.cmny.provider.model.vo.csunsleep.DmcCsunSleepVo;
import com.csun.cmny.provider.model.vo.csunsleep.SleepAndAlert;
import com.csun.cmny.provider.model.vo.device.DmcDeviceAlertLifeRoomVo;
import com.csun.cmny.provider.model.vo.device.DmcDeviceVo;
import com.csun.cmny.provider.model.vo.life.LifeSleepDataIndex;
import com.csun.cmny.provider.model.vo.life.lifeRoomHumidistat;
import com.csun.cmny.provider.service.*;
import com.csun.cmny.provider.utils.DeviceUtils;
import com.csun.cmny.provider.vo.RoomSleepInfo;
import com.csun.cmny.provider.vo.SleepDataVo;
import com.csun.cmny.util.PubUtils;
import com.csun.cmny.util.PublicUtil;
import com.csun.cmny.util.RedisKeyUtil;
import com.csun.cmny.util.wrapper.WrapMapper;
import com.csun.cmny.util.wrapper.Wrapper;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.google.common.collect.Lists;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.BeanUtils;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @Auther: chisj chisj@foxmal.com
 * @Date: 2018-12-12 10:21
 * @Description:
 */
@RestController
@Api(value = "API - OpcGaodeFeignClient", produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
public class DmcDeviceFeignClient implements DmcDeviceFeignApi {

    @Resource
    private DmcDeviceService dmcDeviceService;
    @Resource
    private DmcCsunBodySensorLocationService dmcCsunBodySensorLocationService;
    @Resource
    private DmcCsunButtonLocationService dmcCsunButtonLocationService;
    @Resource
    private DmcRfidLabelOldmanService dmcRfidLabelOldmanService;
    @Resource
    private DmcDeviceUserBindService dmcDeviceUserBindService;
    @Resource
    private DmcCsunHumidistatLocationService dmcCsunHumidistatLocationService;
    @Resource
    private DmcCsunSleepDataService dmcCsunSleepDataService;
    @Resource
    private DmcDeviceAlertService dmcDeviceAlertService;
    @Resource
    private DmcCsunCameraLocationService dmcCsunCameraLocationService;
    @Resource
    private RedisTemplate<String, Object> redisTemplate;
    @Resource
    private DmcCsunGatewayLocationService dmcCsunGatewayLocationService;
    @Resource
    private DmcCsunSleepBindService dmcCsunSleepBindService;
    @Resource
    private OmcRpcService omcRpcService;
    @Resource
    private DeviceUtils deviceUtils;

    @Override
    @ApiOperation(httpMethod = "POST", value = "根据设备Id获取设备信息")
    public Wrapper<DeviceReqDto> getDeviceById(Long deviceId) {

        DeviceReqDto deviceReqDto = dmcDeviceService.getDeviceById(deviceId);

        return WrapMapper.ok(deviceReqDto);
    }

    @Override
    public Wrapper<List<BodySensorReqVo>> queryBodySensorLocationByRoomIds(@RequestParam("roomIdList") List<Integer> roomIdList) {

        List<BodySensorReqVo> bodySensorReqVoList =
                dmcCsunBodySensorLocationService.queryBodySensorLocationByRoomIds(roomIdList);

        return WrapMapper.ok(bodySensorReqVoList);
    }

    @Override
    public Wrapper<List<CsunButtonReqVo>> queryCsunButtonByBedOldmanList(@RequestBody List<BedOldmanCsunButtonReqDto> bedOldmanCsunButtonReqDtoList) {

        List<CsunButtonReqVo> csunButtonReqVoList =
                dmcCsunButtonLocationService.queryCsunButtonByBedOldmanList(bedOldmanCsunButtonReqDtoList);

        return WrapMapper.ok(csunButtonReqVoList);
    }

    @Override
    public Wrapper<List<RfidLabelReqVo>> queryRfidLabelByOldmanIds(@RequestParam("oldmanIdList") List<Integer> oldmanIdList) {

        List<RfidLabelReqVo> rfidLabelReqVoList =
                dmcRfidLabelOldmanService.queryRfidLabelByOldmanIds(oldmanIdList);

        return WrapMapper.ok(rfidLabelReqVoList);
    }

    @Override
    public Wrapper<List<DeviceCountVo>> queryDeviceNumByGroupByDeviceType(Long groupId) {
        List<DeviceCountVo> vos = dmcDeviceService.queryDeviceNumByGroupByDeviceType(groupId);
        return WrapMapper.ok(vos);
    }

    public Wrapper<Integer> breakBindDeviceByOldmanId(Long oldmanId) {
        int ret = dmcDeviceUserBindService.breakBindDeviceByOldmanId(oldmanId);
        return WrapMapper.ok(ret);
    }

    @Override
    public Wrapper<Map> selectDeviceDataByRoomId(Long roomId) {
        HashMap<Object, Object> map = new HashMap<>();
        List<lifeRoomHumidistat> temperature=dmcCsunHumidistatLocationService.selectHumidistatByRoomId(roomId);


        int a=0;
        int b=0;
        if(PublicUtil.isNotEmpty(temperature)){
            for (lifeRoomHumidistat lifeRoomHumidistat : temperature) {
                String gatewayId = lifeRoomHumidistat.getGatewayId();

                String deviceNo = dmcDeviceService.selectByKey(lifeRoomHumidistat.getDeviceId()).getDeviceNo();

                DmcDevice dmcDevice = dmcDeviceService.selectByKey(gatewayId);
                String gatewayNo = null;
                if(PublicUtil.isNotEmpty(dmcDevice)){
                    gatewayNo=dmcDevice.getDeviceNo();
                }

                if(PublicUtil.isNotEmpty(gatewayNo)){
                    CsunGatewayData csunGatewayData = (CsunGatewayData) redisTemplate.opsForValue().get(RedisKeyUtil.getCsunGatewayKey(gatewayNo));
                    if (PublicUtil.isNotEmpty(csunGatewayData)&&csunGatewayData.getStatus().equals("online")){
                        a++;
                    }
                }
                if(PublicUtil.isNotEmpty(deviceNo)){
                    Boolean aBoolean = redisTemplate.hasKey(RedisKeyUtil.getCsunHumidistatOnline(deviceNo));
                    if(aBoolean){
                        b++;
                    }
                }
            }
        }


        if (a>0&&b>0) {
            if(PublicUtil.isNotEmpty(temperature)){
                map.put("temperature",temperature.get(0).getTemperature());
            }else {
                map.put("temperature",null);
            }
        } else {
            map.put("temperature","- -");
        }


        List<LifeSleepDataIndex> lifeSleepDataIndex=dmcCsunSleepDataService.selectDataByRoomId(roomId);

        if(PublicUtil.isNotEmpty(lifeSleepDataIndex)){

            map.put("heartbeat",lifeSleepDataIndex.get(0).getHeartbeat());
            map.put("breath",lifeSleepDataIndex.get(0).getBreath());
            DmcDevice dmcDevice = dmcDeviceService.selectByKey(lifeSleepDataIndex.get(0).getDeviceID());

            String redisKey = RedisKeyUtil.getCsunSleepKey(dmcDevice.getDeviceNo());

            CsunSleepData csunSleepData = (CsunSleepData) redisTemplate.opsForValue().get(redisKey);


            if(csunSleepData.getStatus().equals(DeviceStatusEnum.OFFLINE.getKey())){

                map.put("in_bed","3");
            }else {
                map.put("in_bed",csunSleepData.getInBed().toString());
            }
        }else {
            map.put("heartbeat",null);
            map.put("breath",null);
            map.put("in_bed",null);
        }

        return WrapMapper.ok(map);
    }

    @Override
    public Wrapper<Map> selectAlertDataByRoomId(Long roomId,Long groupId) {

        HashMap<Object, Object> map = new HashMap<>();
       List<DmcDeviceAlertLifeRoomVo> dmcDeviceAlerts=dmcDeviceAlertService.selectAlertDataByRoomId(roomId,groupId);
       map.put("deviceAlert",dmcDeviceAlerts);

        return WrapMapper.ok(map);
    }

    @Override
    public Wrapper<List<String>> getCameraDeviceNoByLifeRoomId(Long roomId) {
        List<String> cameraNoList = dmcCsunCameraLocationService.getCameraDeviceNoByLifeRoomId(roomId);
        return WrapMapper.ok(cameraNoList);
    }

    @Override
    public Wrapper<IsInRoomVO> getIsInRoomStatus(@RequestParam Long roomId) {
        IsInRoomVO vo = dmcDeviceService.getIsInRoomStatus(roomId);
        return WrapMapper.ok(vo);
    }

    @Override
    public Wrapper<List<DeviceReqVo>> listDevice(@RequestParam("deviceIdList") List deviceIdList) {

        List<DeviceReqVo> deviceReqVoList = Lists.newArrayList();
        List<DmcDeviceVo> list = dmcDeviceService.queryDeviceListByIdList(deviceIdList);
        list.forEach(d -> {
            DeviceReqVo deviceReqVo = new DeviceReqVo();
            deviceReqVo.setDeviceId(d.getId());
            deviceReqVo.setDeviceNo(d.getDeviceNo());
            deviceReqVoList.add(deviceReqVo);
        });

        return WrapMapper.ok(deviceReqVoList);
    }

    /**
     * 根据房间Id查询温湿度计数据
     *
     * @param roomIdList the room id list
     *
     * @return the humidistat req vo list
     */
    @Override
    public Wrapper<List<HumidistatReqVo>> queryHumidistatByRoomIds(@RequestParam("roomIdList") List<Integer> roomIdList) {

        List<HumidistatReqVo> humidistatReqVoList =
                dmcCsunHumidistatLocationService.queryHumidistatByRoomIds(roomIdList);

        return WrapMapper.ok(humidistatReqVoList);
    }

    /**
     * 根据房间Id查询摄像头数据
     *
     * @param roomIdList the room id list
     *
     * @return the camera req vo list
     */
    @Override
    public Wrapper<List<CameraReqVo>> queryCameraByRoomIds(@RequestParam("roomIdList") List<Integer> roomIdList) {

        List<CameraReqVo> cameraReqVoList =
                dmcCsunCameraLocationService.queryCameraByRoomIds(roomIdList);

        return WrapMapper.ok(cameraReqVoList);
    }

    /**
     * 根据房间Id查询网关
     *
     * @param roomIdList the room id list
     *
     * @return the gateway req vo
     */
    @Override
    public Wrapper<List<GatewayReqVo>> queryGatewayByRoomIds(@RequestParam("roomIdList") List<Integer> roomIdList) {

        List<GatewayReqVo> gatewayReqVos =
                dmcCsunGatewayLocationService.queryGatewayByRoomIds(roomIdList);

        return WrapMapper.ok(gatewayReqVos);
    }
    //查询床垫数据
    @Override
    public Wrapper<List<Map>> querySleepInfoByRoomId(@RequestParam("ids") ArrayList<Long> ids) {
        List<Map> maps = new ArrayList<>();
        List<LifeSleepDataIndex> lifeSleepDataIndex=dmcCsunSleepDataService.querySleepInfoByRoomId(ids);
        if(lifeSleepDataIndex.size()>0){
            for (LifeSleepDataIndex l:lifeSleepDataIndex) {
                Map map = new HashMap();
                if(PublicUtil.isNotEmpty(lifeSleepDataIndex)){
                    map.put("lifeSleepDataIndex",lifeSleepDataIndex);
                    map.put("oldmanId",l.getOldmanId());
                    map.put("heartbeat",l.getHeartbeat());
                    map.put("breath",l.getBreath());
                    map.put("in_bed",l.getInBed());
                    map.put("id",l.getId());
                    map.put("isHandle",l.getIsHandle());
                }else {
                    map.put("oldmanId",null);
                    map.put("heartbeat",null);
                    map.put("breath",null);
                    map.put("in_bed",null);
                }
                maps.add(map);
            }
        }
        return WrapMapper.ok(maps);
    }
    //查询报警信息
    @Override
    public Wrapper<PageInfo> querySleepAlertInfo(@RequestParam("ids") ArrayList<Long> ids,
                                                             @RequestParam(value = "isHandle" ,required = false) Integer isHandle,
                                                             @RequestParam("pageNum") Integer pageNum,@RequestParam("pageSize") Integer pageSize) {
        PageHelper.startPage(pageNum,pageSize);
        List<DmcDeviceAlert> list = dmcCsunSleepDataService.querySleepAlertInfo(ids, isHandle);
        PageInfo<DmcDeviceAlert> dmcDeviceAlertPageInfo = new PageInfo<>(list);
        return WrapMapper.ok(dmcDeviceAlertPageInfo);
    }
    //查询床垫状态
    @Override
    public Wrapper<List<com.csun.cmny.provider.vo.SleepDataVo>> queryInBed(@RequestParam("deviceIds") List<Long> deviceIds) {
        List<SleepDataVo> sleepDataVos = dmcCsunSleepDataService.queryInBed( deviceIds);
        return WrapMapper.ok(sleepDataVos);
    }
    //查询绑定了床垫的老人
    @Override
    public Wrapper<List<RoomSleepInfo>> querySleepBind(@RequestParam("ids") ArrayList<Long> ids) {
        List<RoomSleepInfo> sleepInfos = dmcCsunSleepDataService.querySleepBind(ids);
        return WrapMapper.ok(sleepInfos);
    }
    //查询床垫时间段是否在床
    @Override
    public Wrapper<List<CsunSleepDataReqVo>> querySleepInbed(@RequestParam("ids") ArrayList<Long> ids,@RequestParam("time") String time) {
       List<CsunSleepDataReqVo> sleepDataReqVos = dmcCsunSleepDataService.querySleepInbed(ids,time);
        return WrapMapper.ok(sleepDataReqVos);
    }
    //查询床垫报警信息
    @Override
    public Wrapper<List<DmcDeviceAlert>> queryAllSleepAlert(@RequestParam("ids") ArrayList<Long> ids) {
        List<DmcDeviceAlert> list = dmcCsunSleepDataService.queryAllSleepAlert(ids);
        return WrapMapper.ok(list);
    }

    //查询床垫绑定
    @Override
    public Wrapper<List<DmcCsunSleepVo>> queryGroupCsunSleepList(@RequestParam("groupId") Long groupId) {
        CsunSleepVo csunSleepPageQuery = new CsunSleepVo();
        csunSleepPageQuery.setGroupId(groupId);
        csunSleepPageQuery.setDeviceType(DmcDeviceTypeEnum.CSUN_SLEEP.getIndex());
        List<DmcCsunSleepVo> dmcCsunSleepVos = dmcCsunSleepBindService.queryGroupCsunSleepList(csunSleepPageQuery);
        for (DmcCsunSleepVo dmcCsunSleepVo : dmcCsunSleepVos) {
            CsunSleepData csunSleepData = (CsunSleepData) redisTemplate.opsForValue()
                    .get(RedisKeyUtil.getCsunSleepKey(dmcCsunSleepVo.getDeviceNo()));

            /*
             * 2020-03-17 xuchongran
             * 改变床垫在线状态判别
             * */
//            if (PublicUtil.isEmpty(csunSleepData)) {
            dmcCsunSleepVo.setStatus(DeviceStatusEnum.OFFLINE.getKey());
//            }
//            else {
//                dmcCsunSleepVo.setStatus(csunSleepData.getStatus());
//            }
            if (!PubUtils.isNull(dmcCsunSleepVo.getBindType())) {
                if(redisTemplate.hasKey(RedisKeyUtil.getCsunSleepOnline(dmcCsunSleepVo.getDeviceNo()))){
                    dmcCsunSleepVo.setStatus(DeviceStatusEnum.ONLINE.getKey());
                }
                dmcCsunSleepVo.setBind(true);
                if (dmcCsunSleepVo.getBindType().equals(DmcCsunSleepBindTypeEnum.LIFE_ROOM.getKey())) {
                    RoomBuildingVo roomBuildingVo = (RoomBuildingVo) redisTemplate
                            .opsForValue().get(RedisKeyUtil.getOmcRoomId(dmcCsunSleepVo.getRoomId()));
                    if (PublicUtil.isNotEmpty(roomBuildingVo)) {
                        dmcCsunSleepVo.setBuildingName(roomBuildingVo.getBuildingName());
                        dmcCsunSleepVo.setFloorNo(roomBuildingVo.getFloorNo());
                        dmcCsunSleepVo.setRoomNo(roomBuildingVo.getRoomNo());
//                        dmcCsunSleepVo.setOldmanId(roomBuildingVo.getOldmanId());
//                        dmcCsunSleepVo.setOldmanName(roomBuildingVo.getOldmanName());
                        List<Integer> bedIdList = omcRpcService.listBedByRoomId(roomBuildingVo.getRoomId());
                        if(bedIdList != null && bedIdList.size() > 0){
                            OldmanBedRoomBuildingVo bov = (OldmanBedRoomBuildingVo) redisTemplate.opsForValue().get(RedisKeyUtil.getOmcBedId(bedIdList.get(0)));
                            dmcCsunSleepVo.setOldmanId(bov.getOldmanId());
                            dmcCsunSleepVo.setOldmanName(bov.getOldmanName());
                        }
                    }
                } else {
                    DeviceBindDto deviceBindDto = new DeviceBindDto();
                    BeanUtils.copyProperties(dmcCsunSleepVo, deviceBindDto);
                    OldmanBedRoomBuildingVo obrvo = deviceUtils.getOldmanBedRoomBuildingVo(deviceBindDto);
                    if (PublicUtil.isNotEmpty(obrvo)) {
                        if (dmcCsunSleepVo.getBindType().equals(DmcCsunSleepBindTypeEnum.OLDMAN.getKey())) {
                            dmcCsunSleepVo.setOldmanName(obrvo.getOldmanName());
                            if (PublicUtil.isNotEmpty(obrvo.getLocation())) {
                                /**
                                 * @date 2019-05-28
                                 * @author chisj
                                 * @desc 显示【房间-床位】 #2812
                                 */
                                if (PublicUtil.isNotEmpty(obrvo.getRoomNo()) && PublicUtil.isNotEmpty(obrvo.getBedNo())) {
                                    dmcCsunSleepVo.setLocation(obrvo.getRoomNo() + "-" + obrvo.getBedNo());
                                } else {
                                    dmcCsunSleepVo.setLocation("--");
                                }
                            }
                        }
                        /**
                         * @date 2019-05-06
                         * @author chisj
                         * @desc 解决老人换床后，依旧显示之前老人信息的bug #1832
                         */
                        // 绑定床位, 老人信息和位置根据床位获取
                        if (dmcCsunSleepVo.getBindType().equals(DmcCsunSleepBindTypeEnum.BED.getKey())) {
                            dmcCsunSleepVo.setOldmanName(obrvo.getOldmanName());
                            /**
                             * @date 2019-05-28
                             * @author chisj
                             * @desc 显示【房间-床位】 #2812
                             */
                            if (PublicUtil.isNotEmpty(obrvo.getRoomNo()) && PublicUtil.isNotEmpty(obrvo.getBedNo())) {
                                dmcCsunSleepVo.setLocation(obrvo.getRoomNo() + "-" + obrvo.getBedNo());
                            } else {
                                dmcCsunSleepVo.setLocation("--");
                            }
                            dmcCsunSleepVo.setOldmanId(obrvo.getOldmanId());
                        }
                    }
                }
            }
        }
        return WrapMapper.ok(dmcCsunSleepVos);
    }
    //查询床垫绑定以及老人基本信息
    @Override
    public Wrapper<SleepAndAlert> queryGroupCsunSleepListByGroupId(@RequestParam("groupId") Long groupId) {
        CsunSleepVo csunSleepPageQuery = new CsunSleepVo();
        csunSleepPageQuery.setGroupId(groupId);
        csunSleepPageQuery.setDeviceType(DmcDeviceTypeEnum.CSUN_SLEEP.getIndex());
        SleepAndAlert sleepAndAlert = new SleepAndAlert();
        List<DmcCsunSleepVo> dmcCsunSleepVos = dmcCsunSleepBindService.queryGroupCsunSleepList(csunSleepPageQuery);
        if(dmcCsunSleepVos.size() == 0){
            return WrapMapper.ok(sleepAndAlert);
        }
        //查询床垫报警
        List<DmcDeviceAlert> deviceAlerts = dmcDeviceAlertService.queryDeviceAlertBySleep(dmcCsunSleepVos);
        //查询床垫状态
        List<DmcCsunSleepDataVo> csunSleepData = dmcCsunSleepDataService.querySleepDateById(dmcCsunSleepVos);
        sleepAndAlert.setCsunSleepVos(dmcCsunSleepVos);
        sleepAndAlert.setDeviceAlerts(deviceAlerts);
        sleepAndAlert.setCsunSleepDatas(csunSleepData);
        return WrapMapper.ok(sleepAndAlert);
    }
}
